package com.glacier.framework.boot.rest.config;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.glacier.framework.boot.rest.response.ObjectToJsonStringMapper;
import com.glacier.framework.boot.rest.response.ResponseAdvice;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

/**
 * date 2023-12-29 22:32
 *
 * @author glacier
 * @version 1.0
 */
@Slf4j
@Configuration
@ConditionalOnClass(ResponseAdvice.class)
public class CustomRestResponseAdviceAutoConfiguration {

    /**
     * 响应处理
     *
     * @param objectToJsonStringMapper jsonMapper
     * @return ResponseAdvice 响应处理
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean(ObjectToJsonStringMapper.class)
    ResponseAdvice responseAdvice(ObjectToJsonStringMapper objectToJsonStringMapper) {
        log.info("ResponseAdvice 实例化");
        return new ResponseAdvice(objectToJsonStringMapper);
    }

    @Configuration
    @ConditionalOnClass(ObjectMapper.class)
    static class JacksonAutoConfiguration {

        /**
         * json 序列化
         *
         * @param builder builder
         * @return ObjectMapper
         */
        @Bean
        @ConditionalOnMissingBean
        ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
            log.info("ObjectMapper 实例化");
            return builder.createXmlMapper(false).build();
        }

        /**
         * json 序列化
         *
         * @param objectMapper objectMapper
         * @return JsonMapper
         */
        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnBean(ObjectMapper.class)
        ObjectToJsonStringMapper jacksonObjectToJsonStringMapper(ObjectMapper objectMapper) {
            log.info("ObjectToJsonStringMapper 实例化");
            return (obj) -> {
                String result;
                try {
                    result = objectMapper.writeValueAsString(obj);
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
                return result;
            };
        }
    }
}
